package com.lebang.service;

import com.lebang.component.RedisClient;
import com.lebang.domain.MemberNewTrade;
import com.lebang.domain.MemberPointInfo;
import com.lebang.domain.MemberPointRecord;
import com.lebang.domain.PointCountSetting;
import com.lebang.entity.RequestHeaders;
import com.lebang.example.MemberPointRecordExample;
import com.lebang.example.PointCountSettingExample;
import com.lebang.mapper.*;
import com.lebang.model.MoneyCategory;
import com.lebang.model.Whether;
import com.lebang.model.enums.buss.RewardType;
import com.lebang.model.enums.buss.TaskCategory;
import com.lebang.service.mongodb.IMemberNewTradeMongodb;
import com.lebang.service.rouseday.RouseDayConfigService;
import com.lebangweb.common.UUIDUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;

import static com.lebang.service.buss.MemberTradeService.CATEGORY_KEY;

/**
 * 金币方法层
 *
 * @Author: hwq
 * @Date: 2019/11/18 11:20
 * @Version 1.0
 */
@Service
@Slf4j
public class PointService {
    @Autowired
    private RedisClient redisClient;
    @Autowired
    private PointCountSettingMapper pointCountSettingMapper;
    @Autowired
    private MemberPointInfoMapper memberPointInfoMapper;
    @Autowired
    private MemberPointRecordMapper recordMapper;
    private static final String KEY = "memberpoint:";
    private static final BigDecimal W= BigDecimal.valueOf(10000);
    @Autowired
    private MemberNewTradeMapper memberNewTradeMapper;
    @Autowired
    private LbbMemberMapper lbbMemberMapper;
    @Autowired
    private IMemberNewTradeMongodb iMemberNewTradeMongodb;
    @Autowired
    private RouseDayConfigService rouseDayConfigService;
    /**
     * 用户增加金币方法
     *
     * @param memberId
     * @param count
     * @param category
     * @return
     */
    public boolean addPoint(String memberId, Integer count, TaskCategory category, RequestHeaders header,String event) {
        String Uuid = UUIDUtil.L();
        try {
            boolean status = redisClient.tryGetDistributedLock(KEY + memberId, Uuid, 10000, 10000);
            if (!status) {
                return false;
            }
            MemberPointInfo info = this.getWallet(memberId);
            memberPointInfoMapper.addPoint(info.getId(), count);
            MemberPointRecord record = new MemberPointRecord();
            record.setHasDeleted(Whether.NO.getDbIndex());
            record.setCreateTime(new Date());
            record.setModifyTime(new Date());
            record.setCategory(category.name());
            record.setType(0);
            record.setCount(count);
            record.setMsg(category.getTitle()+event);
            record.setMemberId(memberId);
            record.setAppStore(header.getAppStore());
            record.setVersion(header.getVersion());
            record.setIpAddr(header.getIpAddr());
            record.setMacAddr(header.getMacAddr());
            record.setImei(header.getImei());
            recordMapper.insertSelective(record);
            this.addRecord(record,new MoneyCategory(Whether.NO,category),header);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            redisClient.releaseDistributedLock(KEY + memberId, Uuid);
        }
    }
    /**
     * 用户增加金币方法
     *
     * @param memberId
     * @param count
     * @param category
     * @return
     */
    public boolean addPointBySdk(String memberId, Integer count, TaskCategory category, String event, RequestHeaders header) {
        String Uuid = UUIDUtil.L();
        try {
            boolean status = redisClient.tryGetDistributedLock(KEY + memberId, Uuid, 10000, 10000);
            if (!status) {
                return false;
            }
            MemberPointInfo info = this.getWallet(memberId);
            memberPointInfoMapper.addPoint(info.getId(), count);
            MemberPointRecord record = new MemberPointRecord();
            record.setHasDeleted(Whether.NO.getDbIndex());
            record.setCreateTime(new Date());
            record.setModifyTime(new Date());
            record.setCategory(category.name());
            record.setType(0);
            record.setCount(count);
            record.setMsg(event);
            record.setMemberId(memberId);
            record.setAppStore(header.getAppStore());
            record.setVersion(header.getVersion());
            record.setIpAddr(header.getIpAddr());
            record.setMacAddr(header.getMacAddr());
            record.setImei(header.getImei());
            recordMapper.insertSelective(record);
            this.addRecord(record,new MoneyCategory(Whether.NO,category),header);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            redisClient.releaseDistributedLock(KEY + memberId, Uuid);
        }
    }
    private void addRecord(MemberPointRecord trade, MoneyCategory moneyCategory,RequestHeaders headers) {
        try {
            MemberNewTrade newTrade = new MemberNewTrade();
            newTrade.setCreateTime(LocalDateTime.now());
            newTrade.setMemberId(trade.getMemberId());
            newTrade.setAppStore(trade.getAppStore());
            newTrade.setVersion(trade.getVersion());
            newTrade.setRemark(trade.getMsg());
            newTrade.setIpAddr(trade.getIpAddr());
            newTrade.setMacAddr(trade.getMacAddr());
            newTrade.setImei(trade.getImei());
            newTrade.setCategory(moneyCategory.getTaskCategory().name());
            newTrade.setCategoryTitle(moneyCategory.getTaskCategory().getTitle());
            newTrade.setType(RewardType.Point.getIndex());
            newTrade.setTimeMillis(System.currentTimeMillis());
            newTrade.setAmount(new BigDecimal(trade.getCount()).divide(W, 8, BigDecimal.ROUND_DOWN));
            newTrade.setMyAmount(moneyCategory.getMyMoney());
            LocalDateTime time = lbbMemberMapper.selectCreaTimeByMemberId(trade.getMemberId());
            if (time != null) {
                if (LocalDate.now().equals(time.toLocalDate())) {
                    newTrade.setIsNewMember(Whether.YES.getDbIndex());
                } else {
                    newTrade.setIsNewMember(Whether.NO.getDbIndex());
                }
            } else {
                newTrade.setIsNewMember(-1);
            }
           // iMemberNewTradeMongodb.insert(newTrade);
            memberNewTradeMapper.insertSelective(newTrade);
            int k=redisClient.hincrby(CATEGORY_KEY+moneyCategory.getTaskCategory().name()+":"+
                    LocalDate.now().format(DateTimeFormatter.ISO_DATE),trade.getMemberId(),1L).intValue();
            redisClient.hincrby(CATEGORY_KEY+"ALL:"+
                    LocalDate.now().format(DateTimeFormatter.ISO_DATE),trade.getMemberId(),1L);
            rouseDayConfigService.endRecord(moneyCategory.getTaskCategory(),k,headers);
        } catch (Exception e) {
            log.error("记录报记录出错601");
            e.printStackTrace();
        }
    }
    /**
     * 获取用户钱包信息
     *
     * @param memberId
     * @return
     */
    public MemberPointInfo getWallet(String memberId) {
        MemberPointInfo info = memberPointInfoMapper.selectByMemberId(memberId);
        if (info == null) {
            initData(memberId);
            info = memberPointInfoMapper.selectByMemberId(memberId);
        }
        return info;
    }

    public void initData(String memberId){
        MemberPointInfo info = new MemberPointInfo();
        info.setCreateTime(new Date());
        info.setModifyTime(new Date());
        info.setMemberId(memberId);
        info.setCount(0);
        info.setTotalCount(0);
        info.setTotalCash(0);
        info.setTodayCount(0);
        memberPointInfoMapper.insertSelective(info);
    }

    /**
     * 金币兑换减少金币
     *
     * @param memberId 用户id
     * @param count    金币数量
     * @return
     */
    public boolean pointCash(String memberId, Integer count, PointCountSetting setting) {
        MemberPointInfo info = this.getWallet(memberId);
        memberPointInfoMapper.subtractPoint(info.getId(), count);
        MemberPointRecord record = new MemberPointRecord();
        record.setHasDeleted(Whether.NO.getDbIndex());
        record.setCreateTime(new Date());
        record.setModifyTime(new Date());
        record.setCategory("金币兑换");
        record.setType(1);
        record.setCount(count);
        record.setMsg(count + "金币兑换" + new BigDecimal(setting.getCount()).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN) + "元");
        record.setMemberId(memberId);
        int i = recordMapper.insertSelective(record);
        return i > 0;

    }
    /**
     * 金币支出金币
     *
     * @param memberId 用户id
     * @param count    金币数量
     * @return
     */
    public boolean pointCash(String memberId, Integer count, String title,String msg) {
        MemberPointInfo info = this.getWallet(memberId);
        memberPointInfoMapper.subtractPoint(info.getId(), count);
        MemberPointRecord record = new MemberPointRecord();
        record.setHasDeleted(Whether.NO.getDbIndex());
        record.setCreateTime(new Date());
        record.setModifyTime(new Date());
        record.setCategory(title);
        record.setType(1);
        record.setCount(count);
        record.setMsg(msg);
        record.setMemberId(memberId);
        int i = recordMapper.insertSelective(record);
        return i > 0;

    }

    public PointCountSetting selectSettingById(Integer settingId) {
        return pointCountSettingMapper.selectByPrimaryKey(settingId);
    }


    /**
     * 获取兑换金币配置
     * @return
     */
    public List<PointCountSetting> selectSetting() {
        PointCountSettingExample example = new PointCountSettingExample();
        example.setOrderByClause("count asc");
        return pointCountSettingMapper.selectByExample(example);
    }

    public List<MemberPointRecord> selectRecordByMemberId(String memberId,Integer type) {
        MemberPointRecordExample example=new MemberPointRecordExample();
        example.setOrderByClause("create_time desc");
        example.setLimit(10);
        example.createCriteria().andMemberIdEqualTo(memberId).andTypeEqualTo(type);
        return recordMapper.selectByExample(example);
    }
    public List<MemberPointRecord> selectTradeRecordByMemberId(String memberId,Integer type,Long page,Integer limit) {
        page=(page-1)*limit;
        MemberPointRecordExample example=new MemberPointRecordExample();
        example.setOffset(page);
        example.setLimit(limit);
        example.setOrderByClause("create_time desc");
        example.setLimit(10);
        example.createCriteria().andMemberIdEqualTo(memberId).andTypeEqualTo(type).andHasDeletedEqualTo(0);
        return recordMapper.selectByExample(example);
    }
}
